﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;


namespace cubeAdjustment
{
    public static class BaseFunction
    {
        /// <summary>
        /// 该函数用于将
        /// </summary>
        /// <param name="dms"></param>
        /// <returns></returns>
        public static double ToRad(double dms)
        {
            double d = Math.Floor(dms);
            double m = Math.Floor((dms - d) * 100.0);
            double s = (dms - d - m / 100.0) * 10000.0;
            return (d + m / 60.0 + s / 3600.0) * Math.PI / 180.0;
        }
        /// <summary>
        /// 该函数用于获得两个坐标的方位角
        /// </summary>
        /// <param name="xA">起始点X坐标</param>
        /// <param name="yA">起始点Y坐标</param>
        /// <param name="xB">终点X坐标</param>
        /// <param name="yB">终点Y坐标</param>
        /// <returns>方位角(弧度)</returns>
        public static double GetAzimuth(double xA, double yA, double xB, double yB)
        {
            if (yB - yA < 0)
                return Math.Atan2(yB - yA, xB - xA) + 2.0 * Math.PI;
            if (xB - xA == 0 && yB - yA >= 0)
                return Math.PI / 2.0;
            if (xB - xA == 0 && yB - yA < 0)
                return Math.PI * 1.5;
            return Math.Atan2(yB - yA, xB - xA);
        }
    }
    /// <summary>
    /// 用于获得坐标方位角
    /// </summary>
    internal class GetCoordinate
    {
        public List<iPoint> points;
        public GetCoordinate(knownData knownData, List<iObserve> observedDatas)
        {
            this.points = new List<iPoint>();
            foreach (iObserve observedData in observedDatas)
            {
                iPoint pA = knownData.pointDatas.Find(item => item.id == observedData.testSiteNum);
                if (pA == null)
                {
                    pA = points.Find(item => item.id == observedData.testSiteNum);
                    if (pA == null)
                    {
                        MessageBox.Show("数据有误");
                        return;
                    }
                }

                iPoint pB = knownData.pointDatas.Find(item => item.id == observedData.originalDatas[0].id);
                if (pB == null)
                {
                    pB = points.Find(item => item.id == observedData.originalDatas[0].id);
                    if (pB == null)
                    {
                        MessageBox.Show("数据有误");
                        return;
                    }
                }

                double alphaAB = BaseFunction.GetAzimuth(pA.x, pA.y, pB.x, pB.y) - observedData.originalDatas[0].value;

                for (int i = 1; i < observedData.originalDatas.Count; i++)
                {
                    var tempP = knownData.pointDatas.Find(item => item.id == observedData.originalDatas[i].id);
                    if (tempP != null)
                    { continue; }

                    if (knownData.pointDatas.Exists(item => item.id == observedData.originalDatas[i].id) || observedData.originalDatas[i].type == "S" || points.Exists(item => item.id == observedData.originalDatas[i].id))
                    { continue; }

                    double xA = pA.x;
                    double yA = pA.y;
                    double sAP = observedData.originalDatas.Find(item => item.id == observedData.originalDatas[i].id && item.type == "S").value;
                    double AlphaAP = alphaAB + BaseFunction.ToRad(observedData.originalDatas[i].value);
                    double cosAlphaAP = Math.Cos(AlphaAP);
                    double sinAlphaAP = Math.Sin(AlphaAP);
                    points.Add(new iPoint(observedData.originalDatas[i].id, xA + sAP * cosAlphaAP, yA + sAP * sinAlphaAP));
                }
            }
        }
    }
}
